﻿using AsterNET.FastAGI;
using AsterNET.FastAGI.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AsterNET.Extensions.FastAGI.Helpers
{
    public enum OriginateType { App, Exten }

    public enum OriginateStatus
    {
        Failed,
        Success,
        Busy,
        Congestion,
        Hangup,
        Ringing,
        Unknown
    }

    public class OriginateHelper
    {
        /// <summary>
        /// This application originates an outbound call and connects it to a specified extension or application. 
        /// This application will block until the outgoing call fails or gets answered. At that point, 
        /// this application will exit with the status variable set and dialplan processing will continue.
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="tech">Channel technology and data for creating the outbound channel. For example, SIP/1234</param>
        /// <param name="type">This should be App or Exten, depending on whether the outbound channel should be connected to an application or extension.</param>
        /// <param name="arg1">If the type is App, then this is the application name. If the type is Exten, then this is the context that the channel will be sent to.</param>
        /// <param name="arg2">If the type is App, then this is the data passed as arguments to the application. If the type is Exten, then this is the extension that the channel will be sent to.</param>
        /// <param name="arg3">If the type is Exten, then this is the priority that the channel is sent to. If the type is App, then this parameter is ignored.</param>
        /// <returns>Status Enum: FAILED, SUCCESS, BUSY, CONGESTION, HANGUP, RINGING or UNKNOWN</returns>
        public static OriginateStatus Originate(
            AGIChannel channel, 
            string tech,
            OriginateType type, 
            string arg1,
            string arg2,
            string arg3)
        {
            string opt;
            if(string.IsNullOrEmpty(arg3))
                opt = string.Format("{0},{1},{2}{3}", 
                    tech, type.ToString(), 
                    arg1, arg2);
            else
                opt = string.Format("{0},{1},{2}{3}{4}", 
                    tech, type.ToString(), 
                    arg1, arg2, arg3);
            channel.SendCommand(new ExecCommand("Originate", opt));

            channel.SendCommand(new GetVariableCommand("ORIGINATE_STATUS"));
            return (OriginateStatus)Enum.Parse(typeof (OriginateStatus), channel.LastReply.Extra, false);
        }

        /// <summary>
        /// This application originates an outbound call and connects it to a specified extension or application. 
        /// This application will block until the outgoing call fails or gets answered. At that point, 
        /// this application will exit with the status variable set and dialplan processing will continue.
        /// </summary>
        /// <param name="tech">Channel technology and data for creating the outbound channel. For example, SIP/1234</param>
        /// <param name="type">This should be App or Exten, depending on whether the outbound channel should be connected to an application or extension.</param>
        /// <param name="arg1">If the type is App, then this is the application name. If the type is Exten, then this is the context that the channel will be sent to.</param>
        /// <param name="arg2">If the type is App, then this is the data passed as arguments to the application. If the type is Exten, then this is the extension that the channel will be sent to.</param>
        /// <param name="arg3">If the type is Exten, then this is the priority that the channel is sent to. If the type is App, then this parameter is ignored.</param>
        /// <returns>ExecCommand ready to execute on a channel</returns>
        public static ExecCommand Originate(
            string tech,
            OriginateType type,
            string arg1,
            string arg2,
            string arg3)
        {
            string opt;
            if (string.IsNullOrEmpty(arg3))
                opt = string.Format("{0},{1},{2}{3}",
                    tech, type.ToString(),
                    arg1, arg2);
            else
                opt = string.Format("{0},{1},{2}{3}{4}",
                    tech, type.ToString(),
                    arg1, arg2, arg3);
            return new ExecCommand("Originate", opt);
        }
    }
}
